home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -seriously_amiga- / shareware / programming / c / amivogl-mdev / src / amiga.c.bak < prev    next >
Text File  |  1998-01-12  |  38KB  |  1,314 lines

  1. /*
  2.  * Vogle driver for the Amiga
  3.  *
  4.  * Written By: Dr. Charles E. Campbell, Jr.
  5.  * Version   : 1.00
  6.  * Date      : September 28, 1993
  7.  *
  8.  */
  9. #include <stdio.h>
  10. // #include <fcntl.h>
  11. #include <errno.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14.  
  15. #include <functions.h>
  16. #include <exec/types.h>
  17. #include <intuition/intuition.h>
  18. #include <libraries/dos.h>
  19. #include <graphics/rastport.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <graphics/text.h>
  22. #include <exec/memory.h>
  23. #include <devices/inputevent.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/intuition_protos.h>
  26. #include <clib/console_protos.h>
  27.  
  28. #include "vogl.h"
  29.  
  30. #define INTUITION_REV    ((unsigned long) 33L)
  31. #define GRAPICS_REV        ((unsigned long) 33L)
  32.  
  33. /* --------------------------------------------------------------------------
  34.  * Definitions Section:
  35.  */
  36. #define SNGLBUFMODE    0    /* default scrbufmode value                    */
  37. #define DBLBUFMODE    1    /* scrbufmode value                            */
  38. #define RAWKEYBUF    128    /* initial size of rawkey buffer conversion    */
  39. #define KEYBUF        256    /* max size of keybuffer to be read            */
  40.  
  41. #define FONTSEP        ';'
  42. #define MAXVRTX        200
  43. #define MAXSTRING    1024
  44.  
  45. #ifdef SASC
  46. #define USESVMODE
  47. #endif
  48.  
  49. #ifdef AZTEC_C
  50. #define MEMTYPE    (MEMF_ANY|MEMF_CLEAR)
  51. #else
  52. #define MEMTYPE    (MEMF_ANY|MEMF_CLEAR)
  53. #endif
  54.  
  55. /* head_link: handles the generation of head-linked lists.  Note that 
  56.  *   each structure is assumed to have the member "nxt".
  57.  *   The new member becomes "head" - ie. oldest is last in the linked list,
  58.  *   the newest is first.
  59.  */
  60. #define head_link(structure,head,fail_msg) {         \
  61.     structure *newstr;                               \
  62.     newstr= (structure *) malloc(sizeof(structure)); \
  63.     if(!newstr) printf("***out of memory*** <%s>\n",fail_msg);   \
  64.     newstr->nxt= head;                               \
  65.     head    = newstr;                                \
  66.     }
  67.  
  68. /* stralloc: allocates new memory for and copies a string into the new mem */
  69. #define stralloc(ptr,string,fail_msg) {                             \
  70.     ptr= (char *) calloc((size_t) strlen(string) + 1,sizeof(char)); \
  71.     if(!ptr) printf("***out of memory*** <%s>\n",fail_msg);                  \
  72.     strcpy(ptr,string);                                             \
  73.     }
  74.  
  75. /* --------------------------------------------------------------------------
  76.  * Typedefs:
  77.  */
  78. typedef struct FontList_str FontList;
  79.  
  80. /* --------------------------------------------------------------------------
  81.  * Data Structures:
  82.  */
  83. struct FontList_str {
  84.     char            *fontspec;
  85.     struct TextFont *textfont;
  86.     FontList        *nxt;
  87.     };
  88.  
  89. /* --------------------------------------------------------------------------
  90.  * Extern Data:
  91.  */
  92. #ifdef AZTEC_C
  93. extern int Enable_Abort;
  94. #else
  95. void __regargs __checkabort (void);
  96. #endif
  97.  
  98. /* --------------------------------------------------------------------------
  99.  * Local Data:
  100.  */
  101. WORD                 *voglareaBuffer= NULL;
  102. struct BitMap        *voglback      = NULL;
  103. struct BitMap        *voglfront     = NULL;
  104. struct DiskFontBase  *DiskfontBase  = NULL;
  105. struct GfxBase       *GfxBase       = NULL;
  106. struct IntuiText     *voglitext     = NULL;
  107. struct IntuitionBase *IntuitionBase = NULL;
  108. struct IOStdReq      *vogl_cd_ioreq = NULL;
  109. struct Library       *ConsoleDevice = NULL;
  110. struct RastPort      *voglrastport  = NULL;
  111. struct Screen        *voglscreen    = NULL;
  112. struct TextAttr      *vogltextattr  = NULL;
  113. struct TmpRas        *vogltmpras    = NULL;
  114. struct Window        *voglwindow    = NULL;
  115.  
  116. static char               useborder       = 0;
  117. static char               scrbufmode      = SNGLBUFMODE;
  118. static char              *rawkeybuf       = NULL;
  119. static int                grfxmode        = 0;
  120. static int                currcolor       = 0;
  121. static UBYTE             *voglstring      = NULL;
  122. static UWORD              scrdepth        = 4;
  123. static UWORD              scrwidth        = 0;
  124. static UWORD              scrheight       = 0;
  125. static UWORD              voglscrbordleft = 0;
  126. static UWORD              voglscrbordright= 0;
  127. static UWORD              voglscrbordtop  = 0;
  128. static UWORD              voglscrbordbttm = 0;
  129. static USHORT             screenviewmode  = HIRES|LACE;
  130. static LONG               qtyrawkeybuf    = 0L;
  131. static FontList          *fontlisthd      = NULL;
  132. static struct InputEvent *voglievent      = NULL;
  133. static PLANEPTR          voglplaneptr     = NULL;
  134.  
  135. /* voglkeybuf
  136.  *   |uuuddddddduuuuu|    u=unused  d=data
  137.  *      ^       ^
  138.  *   ikeybgn    ikeyend   (always point to unused)
  139.  */
  140. static char     voglkeybuf[KEYBUF];
  141. static unsigned ikeyend= 0;            /* points just-past chars in voglkeybuf        */
  142. static unsigned ikeybgn= KEYBUF-1;    /* points just-before chars in voglkeybuf    */
  143.  
  144.  
  145. /* --------------------------------------------------------------------------
  146.  * Local Prototypes:
  147.  */
  148. static int AMIGA_config(char *);                             /* amiga.c         */
  149. static int AMIGA_init(void);                                  /* amiga.c         */
  150. static struct BitMap *makeBitMap(void);                /* amiga.c         */
  151. static int freeBitMap(struct BitMap *);                      /* amiga.c         */
  152. static int AMIGA_exit(void);                                  /* amiga.c         */
  153. static int AMIGA_draw( int, int);                            /* amiga.c         */
  154. static int AMIGA_getkey(void);                                /* amiga.c         */
  155. static int AMIGA_checkkey(void);                              /* amiga.c         */
  156. static int AMIGA_locator( int *, int *);                      /* amiga.c         */
  157. static int AMIGA_clear(void);                                /* amiga.c         */
  158. static int AMIGA_color(int);                                 /* amiga.c         */
  159. static int AMIGA_mapcolor( int, int, int, int);              /* amiga.c         */
  160. static int AMIGA_font(char *);                                /* amiga.c         */
  161. static int AMIGA_char(char);                                 /* amiga.c         */
  162. static int AMIGA_string(char *);                             /* amiga.c         */
  163. static int AMIGA_fill( int, int[], int[]);                   /* amiga.c         */
  164. static int AMIGA_backbuffer(void);                            /* amiga.c         */
  165. static int AMIGA_swapbuffer(void);                            /* amiga.c         */
  166. static int AMIGA_frontbuffer(void);                          /* amiga.c         */
  167. void _AMIGA_devcpy(void);                              /* amiga.c         */
  168.  
  169.  
  170. /* --------------------------------------------------------------------------
  171.  * Device Entry
  172.  *    fontname;height[;{BEIPU}]
  173.  *   B == bold
  174.  *   E == extended
  175.  *   I == italic
  176.  *   P == plain (default)
  177.  *   U == underlined
  178.  */
  179. static DevEntry amigadev = {
  180.     "AMIGA",                /* name of device                                */
  181.     "topaz;9;P",            /* name of small "hardware" font                */
  182.     "topaz;11;P",        /* name of large "hardware" font                */
  183.     AMIGA_backbuffer,    /* initializes double buffering                    */
  184.     AMIGA_char,            /* prints a "hardware" character                */
  185.     AMIGA_checkkey,        /* check if keyboard key hit, return it            */
  186.     AMIGA_clear,            /* clears viewport to background                */
  187.     AMIGA_color,            /* change current color index                    */
  188.     AMIGA_draw,            /* draws line from current to (x,y)                */
  189.     AMIGA_exit,            /* cleans up and allows vogle to exit            */
  190.     AMIGA_fill,            /* does filled polygons                            */
  191.     AMIGA_font,            /* sets up a hardware font                        */
  192.     AMIGA_frontbuffer,    /* switches drawing into front buffer            */
  193.     AMIGA_getkey,        /* gets a char of input                            */
  194.     AMIGA_init,            /* enables graphics                                */
  195.     AMIGA_locator,        /* finds mouse position in vogle device coords    */
  196.     AMIGA_mapcolor,        /* changes color at index to given rgb value    */
  197.     AMIGA_string,        /* prints a string of hardware text                */
  198.     AMIGA_swapbuffer};    /* swaps front and back buffers                    */
  199.  
  200. /* ==========================================================================
  201.  * Source Code:
  202.  */
  203.  
  204. /* AMIGA_config: This function modifies what AMIGA_init does.  It allows the
  205.  * user to control the type of screen and bitmaps used.  Note that one may
  206.  * use extra half-brite mode, too.  I put in ham mode since I expect to
  207.  * attempt to do some shading someday.
  208.  *
  209.  * The AMIGA_init sets up a gimmezerozero window using a custom Screen and
  210.  * BitMap.
  211.  *
  212.  * The config string may include:
  213.  *      b : use border&title on window
  214.  *        d : double buffer mode
  215.  *        e : extra halfbrite mode
  216.  *        h : ham graphics mode
  217.  *      s : single buffer mode
  218.  *        1-5 : 1,2,3, 4, 5 bit planes (2,4,8,16,64 colors, respectively)
  219.  *
  220.  * Screen height will be max and interlaced.
  221.  * Screen width  will be 640 for 1-4 bit planes and 320 otherwise
  222.  */
  223. static int AMIGA_config(char *config)
  224. {
  225. // Enable_Abort=0;
  226.  
  227. for(; *config; ++config) switch(*config) {
  228.  
  229. case 'b':    /* use border on window */
  230.     useborder= 1;
  231.     break;
  232.  
  233. case 'd':    /* double buffer mode    */
  234.     scrbufmode= DBLBUFMODE;
  235.     break;
  236.  
  237. case 'e':    /* extra halfbrite mode    */
  238.     screenviewmode= LACE|EXTRA_HALFBRITE;
  239.     scrdepth     = 6;
  240.     break;
  241.  
  242. case 'h':    /* ham mode                */
  243.     screenviewmode= LACE|HAM;
  244.     scrdepth     = 6;
  245.     break;
  246.  
  247. case 's':    /* single buffer mode */
  248.     scrbufmode= SNGLBUFMODE;
  249.     break;
  250.  
  251. case '1':    /* one bit plane        */
  252.     screenviewmode= LACE|HIRES;
  253.     scrdepth     = 1;
  254.     break;
  255.  
  256. case '2':    /* two bit planes        */
  257.     screenviewmode= LACE|HIRES;
  258.     scrdepth     = 2;
  259.     break;
  260.  
  261. case '3':    /* three bit planes        */
  262.     screenviewmode= LACE|HIRES;
  263.     scrdepth     = 3;
  264.     break;
  265.  
  266. case '4':    /* four bit planes        */
  267.     screenviewmode= LACE|HIRES;
  268.     scrdepth     = 4;
  269.     break;
  270.  
  271. case '5':
  272.     screenviewmode= LACE;
  273.     scrdepth     = 5;
  274.     break;
  275.  
  276. default:
  277.     screenviewmode= LACE|HIRES;
  278.     scrdepth     = 4;
  279.     printf("***warning*** AMIGA_config: bad config<%s> string\n",config);
  280.     break;
  281.     }
  282.  
  283.     return(0);
  284. }
  285.  
  286. /* -------------------------------------------------------------------------- */
  287.  
  288. /* AMIGA_init: initialises drawing canvas to occupy current window
  289.  *  a routine which enables graphics on the device, sets the default
  290.  *  colour map, and sets vdevice.maxS{x,y} and vdevice.minS{x,y} to the
  291.  *  window size in pixels.
  292.  */
  293. static int AMIGA_init(void)
  294. {
  295. int               gx,gy;            /* getprefposandsize x,y    */
  296. int               gxs,gys;            /* getprefposandsize xs,ys    */
  297. struct Screen    *wbscreen=NULL;
  298. struct NewScreen *newscreen=NULL;
  299. struct NewWindow *newwindow=NULL;
  300.  
  301. // Enable_Abort=0;
  302.  
  303. /* don't let user initialize twice (or more!) */
  304. if(IntuitionBase) {
  305.     printf("***warning*** AMIGA_init: attempt to initialize twice!\n");
  306.     return 0;
  307.     }
  308.  
  309. /* allocate some memory needed for the ConsoleDevice */
  310. vogl_cd_ioreq= (struct IOStdReq *)
  311.   AllocMem(sizeof(struct IOStdReq),MEMTYPE);
  312. if(!vogl_cd_ioreq) {
  313.     AMIGA_exit();
  314.     printf("***warning*** unable to allocate a IOStdReq\n");
  315.     goto initproblem;
  316.     }
  317.  
  318. /* open Intuition */
  319. IntuitionBase= (struct IntuitionBase *)
  320.   OpenLibrary((UBYTE *) "intuition.library",INTUITION_REV);
  321. if(IntuitionBase == NULL) {
  322.     AMIGA_exit();
  323.     printf("***warning*** unable to open Intuition Library\n");
  324.     goto initproblem;
  325.     }
  326.  
  327. /* open Graphics */
  328. GfxBase= (struct GfxBase *)
  329.   OpenLibrary((UBYTE *) "graphics.library",INTUITION_REV);
  330. if(GfxBase == NULL) {
  331.     AMIGA_exit();
  332.     printf("***warning*** unable to open Graphics Library\n");
  333.     goto initproblem;
  334.     }
  335.  
  336. /* open DiskFont */
  337. DiskfontBase= (struct DiskFontBase *)
  338.   OpenLibrary((UBYTE *) "diskfont.library",0L);
  339. if(DiskfontBase == NULL) {
  340.     AMIGA_exit();
  341.     printf("***warning*** unable to open DiskFont library\n");
  342.     goto initproblem;
  343.     }
  344.  
  345. /* open ConsoleDevice */
  346. if(OpenDevice((UBYTE *) "console.device",-1L,(struct IORequest *) vogl_cd_ioreq,0L) != 0) {
  347.     AMIGA_exit();
  348.     printf("***warning*** unable to open DiskFont library\n");
  349.     goto initproblem;
  350.     }
  351. ConsoleDevice= (struct Library *) vogl_cd_ioreq->io_Device;
  352.  
  353. /* determine screen width and height from screenviewmode */
  354.  
  355. #ifdef USESVMODE
  356.  
  357. /* this code uses screenviewmode by itself, setting up standard
  358.  * height and width
  359.  */
  360. scrwidth= 640;
  361. if( (screenviewmode & HAM)   ||
  362.    !(screenviewmode & HIRES) ||
  363.     (screenviewmode & EXTRA_HALFBRITE)) scrwidth= 320;
  364. scrheight= 256;
  365. if(screenviewmode & LACE) scrheight= 400;
  366.  
  367. #else
  368.  
  369. /* lock WorkBench screen and query it for its dimensions */
  370. wbscreen= LockPubScreen((UBYTE *) "Workbench");
  371. if(wbscreen) {
  372.     scrheight= wbscreen->Height;
  373.     scrwidth = wbscreen->Width;
  374.  
  375.     
  376.     if     ( (wbscreen->ViewPort.Modes & LACE)  && !(screenviewmode & LACE))  scrheight/= 2;
  377.     else if(!(wbscreen->ViewPort.Modes & LACE)  &&  (screenviewmode & LACE))  scrheight*= 2;
  378.     if     ( (wbscreen->ViewPort.Modes & HIRES) && !(screenviewmode & HIRES)) scrwidth /= 2;
  379.     else if(!(wbscreen->ViewPort.Modes & HIRES) &&  (screenviewmode & HIRES)) scrwidth *= 2;
  380.  
  381.     voglscrbordtop  = wbscreen->WBorTop + wbscreen->Font->ta_YSize + 1;
  382.     UnlockPubScreen(NULL,wbscreen);
  383.     }
  384. else voglscrbordtop= 0;
  385. #endif
  386.  
  387. /* allocate a NewScreen in CHIP memory */
  388. newscreen= AllocMem(sizeof(struct NewScreen),MEMTYPE);
  389. if(!newscreen) {
  390.     AMIGA_exit();
  391.     printf("***warning*** unable to allocate a NewScreen\n");
  392.     goto initproblem;
  393.     }
  394.  
  395. /* set up both front and back BitMaps.  Note that Vogl signals
  396.  * use of double buffering after this function is called
  397.  * (the doublebuffer() function calls AMIGA_backbuffer
  398.  * which begins backbuffering)
  399.  */
  400. voglfront= makeBitMap();
  401. if(!voglfront) {
  402.     AMIGA_exit();
  403.     printf("***warning*** unable to allocate front BitMap\n");
  404.     goto initproblem;
  405.     }
  406.  
  407. voglback= makeBitMap();
  408. if(!voglback) {
  409.     AMIGA_exit();
  410.     printf("***warning*** unable to allocate back BitMap\n");
  411.     goto initproblem;
  412.     }
  413.  
  414. /* initialize NewScreen */
  415. newscreen->LeftEdge    = 0;
  416. newscreen->TopEdge     = 0;
  417. newscreen->Width       = scrwidth;
  418. newscreen->Height      = scrheight;
  419. newscreen->Depth       = scrdepth;
  420. newscreen->DetailPen   = 1;
  421. newscreen->BlockPen    = 0;
  422. newscreen->ViewModes   = windowviewmode;
  423. newscreen->Type        = CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET;
  424. newscreen->Font        = (struct TextAttr *) NULL;
  425. newscreen->DefaultTitle= (UBYTE *) NULL;
  426. newscreen->CustomBitMap= voglfront;
  427.  
  428. voglscreen             = wbscreen;
  429. /*
  430. voglscreen             = OpenScreen(newscreen);
  431. FreeMem(newscreen,sizeof(struct NewScreen));
  432. */
  433. if(!voglscreen) {
  434.     AMIGA_exit();
  435.     printf("***warning*** unable to open a Screen\n");
  436.     goto initproblem;
  437.     }
  438.  
  439. /* allocate and initialize a window */
  440. newwindow= AllocMem((LONG) sizeof(struct NewWindow),MEMTYPE);
  441. if(!newwindow) {
  442.     AMIGA_exit();
  443.     printf("***warning*** unable to allocate a NewWindow\n");
  444.     goto initproblem;
  445.     }
  446.  
  447. /* get user-specified initial window position and size
  448.  *  The user specifies these parameters with
  449.  *
  450.  *  prefposition(long x,long y)
  451.  *  prefsize(long xs,long ys)
  452.  *
  453.  * *prior* to calling winopen() or ginit().
  454.  * Vogl initializes gx, gy, gxs, gys to -1
  455.  */
  456. getprefposandsize(&gx,&gy,&gxs,&gys);
  457. if(gx  < 0 || scrwidth  < gx)  gx = 0;
  458. if(gy  < 0 || scrheight < gy)  gy = 0;
  459. if(gxs < 0 || scrwidth  < gxs) gxs= scrwidth;
  460. if(gys < 0 || scrheight < gys) gys= scrheight;
  461.  
  462. /* the amiga driver's standard window */
  463. newwindow->LeftEdge   = (SHORT) gx;
  464. newwindow->TopEdge    = (SHORT) gy;
  465. newwindow->Width      = (SHORT) gxs;
  466. newwindow->Height     = (SHORT) gys;
  467. newwindow->DetailPen  = (UBYTE) -1;
  468. newwindow->BlockPen   = (UBYTE) -1;
  469. newwindow->IDCMPFlags = (ULONG) IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY;
  470. newwindow->Flags      = REPORTMOUSE | ACTIVATE | RMBTRAP;
  471. newwindow->FirstGadget= (struct Gadget *) NULL;
  472. newwindow->CheckMark  = (struct Image *) NULL;
  473. newwindow->Title      = (UBYTE *) NULL;
  474. newwindow->Screen     = voglscreen;
  475. newwindow->BitMap     = voglfront;
  476. newwindow->MinWidth   =  0;
  477. newwindow->MinHeight  =  0;
  478. newwindow->MaxHeight  = ~0;
  479. newwindow->MaxWidth   = ~0;
  480. newwindow->Type       = CUSTOMSCREEN;
  481.  
  482. /* configuration modifications */
  483. if(!useborder) newwindow->Flags|= BORDERLESS;
  484. else {
  485.     int Yfont;
  486.     if(vdevice.wintitle && vdevice.wintitle[0]) {
  487.         newwindow->Title= (UBYTE *) vdevice.wintitle;
  488.         }
  489.     Yfont             = voglscreen->Font? voglscreen->Font->ta_YSize : 0;
  490.     voglscrbordtop    = voglscreen->WBorTop + Yfont + 1;
  491.     voglscrbordbttm   = voglscreen->WBorBottom;
  492.     voglscrbordleft   = voglscreen->WBorLeft;
  493.     voglscrbordright  = voglscreen->WBorRight;
  494.     }
  495.  
  496. /* open the window */
  497. voglwindow= OpenWindow(newwindow);
  498. FreeMem(newwindow,sizeof(struct NewWindow));
  499. if(!voglwindow) {
  500.     AMIGA_exit();
  501.     printf("***warning*** unable to allocate a NewWindow\n");
  502.     goto initproblem;
  503.     }
  504.  
  505. /* set voglrastport up */
  506. voglrastport               = &voglscreen->RastPort;
  507. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap=
  508.   (scrbufmode == DBLBUFMODE)? voglback : voglfront;
  509.  
  510. /* initialize areaBuffer (5 bytes, not words, per vertex) */
  511. voglareaBuffer= (WORD *) AllocMem((LONG) 5*MAXVRTX,MEMTYPE);
  512. if(!voglareaBuffer) {
  513.     AMIGA_exit();
  514.     printf("***warning*** unable to initialize areaBuffer for %d vertices\n",MAXVRTX);
  515.     goto initproblem;
  516.     }
  517.  
  518. voglrastport->AreaInfo= (struct AreaInfo *)
  519.   AllocMem((LONG) sizeof(struct AreaInfo),MEMTYPE);
  520. if(!voglrastport->AreaInfo) {
  521.     AMIGA_exit();
  522.     printf("***warning*** unable to initialize areaInfo\n");
  523.     goto initproblem;
  524.     }
  525. InitArea(voglrastport->AreaInfo,voglareaBuffer,MAXVRTX);
  526.  
  527. /* initialize a TmpRas */
  528. vogltmpras= (struct TmpRas *)
  529.   AllocMem((LONG) sizeof(struct TmpRas),MEMTYPE);
  530. if(!vogltmpras) {
  531.     AMIGA_exit();
  532.     printf("***warning*** unable to allocate a TmpRas\n");
  533.     goto initproblem;
  534.     }
  535.  
  536. voglplaneptr= (PLANEPTR) AllocRaster(scrwidth,scrheight);
  537. if(voglplaneptr) {
  538.     voglrastport->TmpRas= (struct TmpRas *)
  539.       InitTmpRas(vogltmpras,voglplaneptr,RASSIZE(scrwidth,scrheight));
  540.     }
  541. else {
  542.     AMIGA_exit();
  543.     printf("***warning*** unable to allocate a %dx%d raster for TmpRas\n",
  544.       scrwidth,scrheight);
  545.     goto initproblem;
  546.     }
  547.  
  548.  
  549. /* don't outline area fills with the OPen (outline color pen) */
  550. BNDRYOFF(voglrastport);
  551.  
  552. /* set up strings and fonts */
  553. voglitext   = (struct IntuiText *) AllocMem((LONG) sizeof(struct IntuiText),MEMTYPE);
  554. voglstring  = (UBYTE *)            AllocMem((LONG) MAXSTRING*sizeof(UBYTE),MEMTYPE);
  555. vogltextattr= (struct TextAttr *)  AllocMem((LONG) sizeof(struct TextAttr),MEMTYPE);
  556.  
  557. /* optionally set up double buffering via AMIGA_backbuffer() */
  558. if(scrbufmode == DBLBUFMODE) AMIGA_backbuffer();
  559.  
  560. /* initial rawkey buffer allocation */
  561. if(!rawkeybuf) {
  562.     qtyrawkeybuf= RAWKEYBUF;
  563.     rawkeybuf   = (char *) AllocMem(qtyrawkeybuf,MEMTYPE);
  564.  
  565.     if(!rawkeybuf) {    /* terminate on no buffer */
  566.         AMIGA_exit();
  567.         printf("***warning*** unable to allocate a %ld byte buffer for rawkeys\n",
  568.           qtyrawkeybuf);
  569.         goto initproblem;
  570.         }
  571.     }
  572.  
  573. /* allocate an InputEvent */
  574. voglievent= (struct InputEvent *) AllocMem(sizeof(struct InputEvent),MEMTYPE);
  575. if(!voglievent) {
  576.     AMIGA_exit();
  577.     printf("***warning*** unable to allocate an InputEvent\n");
  578.     goto initproblem;
  579.     }
  580.  
  581. /* initialize vogl screensize variables*/
  582. vdevice.sizeSx= scrwidth  - 1;        /* x: upper right corner    */
  583. vdevice.sizeSy= scrheight - 1;        /* y: upper right corner    */
  584. vdevice.depth = scrdepth;            /* z: qty bitplanes            */
  585. vdevice.sizeX = vdevice.sizeY= (scrheight < scrwidth)? scrheight : scrwidth;
  586.  
  587. /* initialize the colormap */
  588. AMIGA_mapcolor(0, 0, 0, 0);            /* black                    */
  589. AMIGA_mapcolor(1,15, 0, 0);            /* red                        */
  590. if(scrdepth >= 2) {
  591.     AMIGA_mapcolor(2, 0,15, 0);        /* green                    */
  592.     AMIGA_mapcolor(3,15,15, 0);        /* yellow                    */
  593.     if(scrdepth >= 3) {
  594.         int icolor;
  595.         AMIGA_mapcolor(4, 0, 0,15);    /* blue                        */
  596.         AMIGA_mapcolor(5,15, 0,15);    /* magenta                    */
  597.         AMIGA_mapcolor(6, 0,15,15);    /* cyan                        */
  598.         AMIGA_mapcolor(7,15,15,15);    /* white                    */
  599.  
  600.         /* make the rest, if any, black */
  601.         for(icolor= 8; icolor < (1<<scrdepth); ++icolor)
  602.           AMIGA_mapcolor(icolor,0,0,0);
  603.         }
  604.     }
  605.  
  606. return 1;
  607.  
  608. initproblem:
  609. return(0);
  610. }
  611.  
  612. /* -------------------------------------------------------------------------- */
  613.  
  614. /* makeBitMap: this function sets up one bitmap.  Double buffering, of
  615.  * course, requires two bitmaps.
  616.  */
  617. static struct BitMap *makeBitMap(void)
  618. {
  619. int            idepth;
  620. struct BitMap *bitmap=NULL;
  621.  
  622. /* allocate BitMap itself */
  623. bitmap= AllocMem((LONG) sizeof(struct BitMap),MEMTYPE);
  624.  
  625. if(bitmap) {
  626.     InitBitMap(bitmap,(LONG) scrdepth,(LONG) scrwidth,(LONG) scrheight);
  627.  
  628.     for(idepth= 0; idepth < scrdepth; ++idepth) {
  629.         bitmap->Planes[idepth]= (PLANEPTR) AllocRaster(scrwidth,scrheight);
  630.         if(!bitmap->Planes[idepth]) {    /* unable to get enough memory */
  631.             for(--idepth; idepth >= 0; --idepth)
  632.               FreeRaster(bitmap->Planes[idepth],scrwidth,scrheight);
  633.             FreeMem(bitmap,(LONG) sizeof(struct BitMap));
  634.             break;
  635.             }
  636.         BltClear(bitmap->Planes[idepth],(scrwidth>>3)*scrheight,1);
  637.         }
  638.     }
  639.  
  640. return bitmap;
  641. }
  642.  
  643. /* -------------------------------------------------------------------------- */
  644.  
  645. /* freeBitMap: this function frees up memory used by a BitMap */
  646. static int freeBitMap(struct BitMap *bitmap)
  647. {
  648. int idepth;
  649.  
  650.     for(idepth= scrdepth-1; idepth >= 0; --idepth) {
  651.         FreeRaster(bitmap->Planes[idepth],scrwidth,scrheight);
  652.     }
  653.     FreeMem(bitmap,(LONG) sizeof(struct BitMap));
  654.     return(0);
  655. }
  656.  
  657. /* -------------------------------------------------------------------------- */
  658.  
  659. /* AMIGA_exit: cleans up before returning the window to normal
  660.  *  Note: I've designed this driver so that it can be re-opened.
  661.  */
  662. static int AMIGA_exit(void)
  663. {
  664. FontList *prvfontlist;
  665.  
  666. /* clear back screen */
  667. if(voglscreen) SetRast(&(voglscreen->RastPort),(unsigned long) 0);
  668.  
  669. /* close open Fonts and clean up memory use */
  670. while(fontlisthd) {
  671.     CloseFont(fontlisthd->textfont);
  672.     free((char *) fontlisthd->fontspec);
  673.     fontlisthd->textfont= NULL;
  674.     fontlisthd->fontspec= NULL;
  675.     prvfontlist         = fontlisthd;
  676.     fontlisthd          = fontlisthd->nxt;
  677.     free((char *) prvfontlist);
  678.     }
  679. fontlisthd= NULL;
  680.  
  681. /* free up rawkey buffer */
  682. if(voglievent) FreeMem(voglievent,sizeof(struct InputEvent));
  683. if(rawkeybuf)  FreeMem(rawkeybuf,qtyrawkeybuf);
  684.  
  685. if(vogltextattr->ta_Name) {
  686.     int slen;
  687.     slen= strlen((char *) vogltextattr->ta_Name);
  688.     if(slen & 1) ++slen;
  689.     FreeMem(vogltextattr->ta_Name,slen*sizeof(char));
  690.     vogltextattr->ta_Name= NULL;
  691.     }
  692. if(vogltextattr) FreeMem(vogltextattr,sizeof(struct TextAttr));
  693. if(voglstring)   FreeMem(voglstring,MAXSTRING*sizeof(UBYTE));
  694. if(voglitext)    FreeMem(voglitext,sizeof(struct IntuiText));
  695. vogltextattr= NULL;
  696. voglstring  = NULL;
  697. voglitext   = NULL;
  698.  
  699. if(voglplaneptr) {
  700.     FreeRaster(voglplaneptr,scrwidth,scrheight);
  701.     voglplaneptr= NULL;
  702.     }
  703.  
  704. if(vogltmpras) {
  705.     FreeMem(vogltmpras,sizeof(struct TmpRas));
  706.     }
  707. voglrastport->TmpRas= vogltmpras= NULL;
  708.  
  709. if(voglrastport->AreaInfo) {
  710.     FreeMem(voglrastport->AreaInfo,sizeof(struct AreaInfo));
  711.     }
  712. voglrastport->AreaInfo= NULL;
  713.  
  714. if(voglareaBuffer) {
  715.     FreeMem(voglareaBuffer,5*MAXVRTX);
  716.     }
  717. voglareaBuffer= NULL;
  718.  
  719. if(voglwindow) {
  720.     CloseWindow(voglwindow);
  721.     }
  722. voglwindow= NULL;
  723.  
  724. if(voglscreen) {
  725.     CloseScreen(voglscreen);
  726.     }
  727. voglscreen= NULL;
  728.  
  729. /* free up BitMaps */
  730. if(voglback)  freeBitMap(voglback);
  731. if(voglfront) freeBitMap(voglfront);
  732. voglfront= voglback= NULL;
  733.  
  734. /* close down Libraries */
  735. if(ConsoleDevice) {
  736.     CloseDevice((struct IORequest *) vogl_cd_ioreq);
  737.     }
  738. ConsoleDevice= NULL;
  739. if(DiskfontBase) {
  740.     CloseLibrary((struct Library *) DiskfontBase);
  741.     }
  742. DiskfontBase= NULL;
  743. if(GfxBase) {
  744.     CloseLibrary((struct Library *) GfxBase);
  745.     }
  746. GfxBase= NULL;
  747. if(IntuitionBase) {
  748.     CloseLibrary((struct Library *) IntuitionBase);
  749.     }
  750. IntuitionBase= NULL;
  751.  
  752. /* free up memory for Console Device */
  753. if(vogl_cd_ioreq) {
  754.     FreeMem(vogl_cd_ioreq,sizeof(struct IOStdReq));
  755.     }
  756. vogl_cd_ioreq= NULL;
  757.  
  758. return(0);
  759. }
  760.  
  761. /* -------------------------------------------------------------------------- */
  762.  
  763. /* AMIGA_draw: draws a line from the current graphics position to (x, y) */
  764. static int AMIGA_draw(  int x,  int y)
  765. {
  766.     Move(voglrastport,vdevice.cpVx,vdevice.sizeSy - vdevice.cpVy);
  767.     Draw(voglrastport,x,vdevice.sizeSy - y);
  768.     return(0);
  769. }
  770.  
  771. /* -------------------------------------------------------------------------- */
  772.  
  773. /* AMIGA_getkey: grab a character from the keyboard
  774.  *  (empties voglkeybuf)
  775.  */
  776. static int AMIGA_getkey(void)
  777. {
  778. int   key;
  779. int   mb,wx,wy;        /* to make AMIGA_locator happy */
  780. int   newikeybgn;
  781. ULONG signals;
  782.  
  783. newikeybgn= ikeybgn + 1;
  784. if(newikeybgn >= KEYBUF) newikeybgn= 0;
  785.  
  786. if(newikeybgn != ikeyend) {
  787.     /* update ikeybgn index and get key from voglkeybuf */
  788.     ikeybgn= newikeybgn;
  789.     key    = voglkeybuf[ikeybgn];
  790.     }
  791.  
  792. else {
  793.  
  794.     /* block until a key is hit */
  795.     do {
  796.         signals= Wait(1L << voglwindow->UserPort->mp_SigBit);
  797.         if(signals & (1L << voglwindow->UserPort->mp_SigBit)) {
  798.             mb= AMIGA_locator(&wx,&wy);
  799.             }
  800.         } while(newikeybgn == ikeyend);
  801.  
  802.     /* update ikeybgn index and get key from voglkeybuf */
  803.     ikeybgn= newikeybgn;
  804.     key    = voglkeybuf[ikeybgn];
  805.     }
  806.  
  807. return key;
  808. }
  809.  
  810. /* -------------------------------------------------------------------------- */
  811.  
  812. /* AMIGA_checkkey: Check if a keyboard key has been hit. If so return it
  813.  *  Otherwise, return 0.  Note: this function does actually read the
  814.  *  key (ie. remove it from the buffer) if one has been hit.  That's
  815.  *  the way the qread/qtest functions like it.
  816.  */
  817. static int AMIGA_checkkey(void)
  818. {
  819. int key;
  820. int mb,wx,wy;        /* to make AMIGA_locator happy */
  821. int newikeybgn;
  822.  
  823.  
  824. /* fill up rawkeybuf with any pending key hits */
  825. mb = AMIGA_locator(&wx,&wy);
  826.  
  827. newikeybgn= ikeybgn + 1;
  828. if(newikeybgn >= KEYBUF) newikeybgn= 0;
  829. if(newikeybgn != ikeyend) {
  830.     ikeybgn= newikeybgn;
  831.     key    = voglkeybuf[ikeybgn];
  832.     }
  833. else key= 0;
  834.  
  835. return key;
  836. }
  837.  
  838. /* -------------------------------------------------------------------------- */
  839.  
  840. /* AMIGA_handlekey: this function handles RAWKEYs  (fills up voglkeybuf)
  841.  *     voglkeybuf                                      voglkeybuf
  842.  *   |uuuddddddduuuuu|    u=unused  d=data            |ddddduuuuuuudd|
  843.  *      ^       ^                                           ^     ^
  844.  *   ikeybgn    ikeyend   (always point to unused)     ikeyend    ikeybgn
  845.  */
  846. static void AMIGA_handlekey(struct IntuiMessage *Imsg)
  847. {
  848. int      dbl=0;
  849. LONG     numchars;
  850. unsigned newikeyend;
  851.  
  852. /* convert rawkey message into a vanilla key */
  853. do {
  854.     voglievent->ie_Class           = IECLASS_RAWKEY;
  855.     voglievent->ie_Code            = Imsg->Code;
  856.     voglievent->ie_Qualifier       = Imsg->Qualifier;
  857.     voglievent->ie_position.ie_addr= *((APTR*) Imsg->IAddress);
  858.  
  859.     numchars= RawKeyConvert(voglievent,(STRPTR) rawkeybuf,qtyrawkeybuf-1,NULL);
  860.     dbl    = numchars == -1 && !rawkeybuf[0];
  861.  
  862.     if(dbl) {    /* double size of rawkeybuf to enable conversion */
  863.         FreeMem(rawkeybuf,qtyrawkeybuf);
  864.         qtyrawkeybuf<<= 1;
  865.         rawkeybuf     = AllocMem(qtyrawkeybuf,MEMTYPE);
  866.         if(!rawkeybuf) {    /* unable to double rawkey buffer! */
  867.             qtyrawkeybuf= 0;
  868.             AMIGA_exit();
  869.             }
  870.         }
  871.     } while(dbl);
  872.  
  873. /* numchars contains the number of characters placed within the rawkeybuf.
  874.  * Key up events and key sequences which do not generate any data for the
  875.  * program (deadkeys, already intercepted sequences, etc) will return zero.
  876.  *
  877.  * Special keys (HELP, cursor keys, FKeys, etc) return multiple characters
  878.  * that have to be parsed below.
  879.  *
  880.  * There are a number of qualifiers available, most of which are currently
  881.  * being ignored by this vogl-amiga driver.  However, for reference purposes:
  882.  *
  883.  * (Imsg->Code & 0x80)? key-up : key-down
  884.  * 
  885.  *  Imsg->Qualifier can be "anded" with
  886.  * 
  887.  *    IEQUALIFIER_CAPSLOCK       IEQUALIFIER_LSHIFT         IEQUALIFIER_RBUTTON       
  888.  *    IEQUALIFIER_CONTROL        IEQUALIFIER_MIDBUTTON      IEQUALIFIER_RCOMMAND      
  889.  *    IEQUALIFIER_INTERRUPT      IEQUALIFIER_MULTIBROADCAST IEQUALIFIER_RELATIVEMOUSE 
  890.  *    IEQUALIFIER_LALT           IEQUALIFIER_NUMERICPAD     IEQUALIFIER_REPEAT        
  891.  *    IEQUALIFIER_LCOMMAND       IEQUALIFIER_RALT           IEQUALIFIER_RSHIFT        
  892.  *    IEQUALIFIER_LEFTBUTTON     
  893.  */
  894.  
  895. /* key is pressed down */
  896. if(!(Imsg->Code & 0x80)) {
  897.  
  898.     /* handlekey only accepts alphameric (assumed to be caps), numeric, and unshifted
  899.      * punctuation.  Report sequences (function keys, help, cursor keys, etc) are
  900.      * ignored!
  901.      */
  902.     newikeyend= ikeyend + 1;
  903.     if(newikeyend >= KEYBUF) newikeyend= 0;
  904.     
  905.     if(newikeyend != ikeybgn && rawkeybuf[0] != 0x9b) {    /* 0x9b is a report sequence */
  906.         if     (islower(rawkeybuf[0]))   rawkeybuf[0]= toupper(rawkeybuf[0]);    /* lower -> upper    */
  907.         else if(rawkeybuf[0] == '\177')  rawkeybuf[0]= '\020';                    /* DEL key mapping    */
  908.         voglkeybuf[ikeyend]= rawkeybuf[0];
  909.         ikeyend            = newikeyend;
  910.         }
  911.     }
  912.  
  913. }
  914.  
  915. /* --------------------------------------------------------------------- */
  916.  
  917. /* AMIGA_locator:
  918.  *    return the window location of the cursor,
  919.  *  plus which mouse button, if any, has been pressed.
  920.  *
  921.  * Bit   0     1      2    is 1 when button is pressed down
  922.  *     |left|middle|right| is 0 when button is released
  923.  */
  924. static int AMIGA_locator(  int *wx,  int *wy)
  925. {
  926. int                  mb  = 0;
  927. struct Message      *Mmsg= NULL;
  928. struct IntuiMessage *Imsg= NULL;
  929.  
  930. /* get current mouse position */
  931. *wx= voglwindow->MouseX;
  932. *wy= vdevice.sizeSy - voglwindow->MouseY;
  933.  
  934. while(Mmsg= GetMsg(voglwindow->UserPort)) {
  935.     Imsg= (struct IntuiMessage *) Mmsg;
  936.  
  937.     switch(Imsg->Class) {
  938.  
  939.     case IDCMP_MOUSEBUTTONS:
  940.  
  941.         switch(Imsg->Code) {
  942.  
  943.         case SELECTDOWN:    /* left   mouse pressed        */
  944.             mb|= 01;
  945.             break;
  946.  
  947.         case SELECTUP:        /* left   mouse released    */
  948.             mb&= ~01;
  949.             break;
  950.  
  951.         case MIDDLEDOWN:    /* middle mouse pressed        */
  952.             mb|= 02;
  953.             break;
  954.  
  955.         case MIDDLEUP:        /* middle mouse released    */
  956.             mb&= ~02;
  957.             break;
  958.  
  959.         case MENUDOWN:        /* right  mouse pressed        */
  960.             mb|= 04;
  961.             break;
  962.  
  963.         case MENUUP:        /* right  mouse released    */
  964.             mb&= ~04;
  965.             break;
  966.  
  967.         default:
  968.             break;
  969.             }
  970.         break;
  971.  
  972.     case IDCMP_RAWKEY:        /* a key was hit/released    */
  973.         AMIGA_handlekey(Imsg);
  974.         break;
  975.  
  976.     default:                /* unsupported Intuimessage    */
  977.         break;
  978.         }
  979.  
  980.     ReplyMsg(Mmsg);
  981.     }
  982.  
  983. return mb;
  984. }
  985.  
  986. /* -------------------------------------------------------------------------- */
  987.  
  988. /* AMIGA_clear: Clear the screen to current color */
  989. static int AMIGA_clear(void)
  990. {
  991.     SetRast(voglrastport,(unsigned long) currcolor);
  992.     return(0);
  993. }
  994.  
  995. /* -------------------------------------------------------------------------- */
  996.  
  997. /* AMIGA_color: set the current drawing color index */
  998. static int AMIGA_color(int icolor)
  999. {
  1000.     currcolor= icolor;                /* used by string/char rendering */
  1001.     SetAPen(voglrastport,icolor);
  1002.     return(0);
  1003. }
  1004.  
  1005. /* -------------------------------------------------------------------------- */
  1006.  
  1007. /* AMIGA_mapcolor: change index icolor in the color map to the appropriate
  1008.  *  r, g, b, value.
  1009.  */
  1010. static int AMIGA_mapcolor(  int icolor,  int r,  int g,  int b)
  1011. {
  1012. if(icolor >= (1<<scrdepth)) {
  1013.     return(0);
  1014.     }
  1015.  
  1016. SetRGB4(&voglscreen->ViewPort,
  1017.   (long)          icolor,
  1018.   (unsigned long) r,
  1019.   (unsigned long) g,
  1020.   (unsigned long) b);
  1021.  
  1022.     return(0);
  1023. }
  1024.  
  1025. /* -------------------------------------------------------------------------- */
  1026.  
  1027. /* AMIGA_font: Set up a hardware font. Return 1 on success 0 otherwise
  1028.  *  I have come up with a little convention for the fontspec:
  1029.  *    fontname;height[;{BEIPU}]
  1030.  *   B == bold
  1031.  *   E == extended
  1032.  *   I == italic
  1033.  *   P == plain (default)
  1034.  *   U == underlined
  1035.  *
  1036.  *  Returns: 0=failure-to-open
  1037.  *           1=successful font open
  1038.  */
  1039. static int AMIGA_font(char *fontspec)
  1040. {
  1041. char             type='P';        /* font spec type            */
  1042. char            *fsh;            /* ptr to font spec height    */
  1043. char            *fst;            /* ptr to font spec type    */
  1044. // int              h;                /* height                    */
  1045. int              slen;            /* length of fontname        */
  1046. FontList        *fontlist    = NULL;
  1047. struct TextFont *vogltextfont= NULL;
  1048. static FontList *oldfontlist = NULL;
  1049.  
  1050. /* check over FontList for fontspec */
  1051. for(fontlist= fontlisthd; fontlist; fontlist= fontlist->nxt) {
  1052.  
  1053.     if(!strcmp(fontlist->fontspec,fontspec)) {
  1054.     
  1055.         if(fontlist == oldfontlist) {    /* font unchanged! */
  1056.             return(0);
  1057.             }
  1058.  
  1059.         vdevice.hheight= fontlist->textfont->tf_YSize;
  1060.         vdevice.hwidth = fontlist->textfont->tf_XSize;
  1061.     
  1062.         /* set the font */
  1063.         SetFont(voglrastport,fontlist->textfont);
  1064.         oldfontlist= fontlist;
  1065.         return 1;
  1066.         }
  1067.     }
  1068.  
  1069. /* get font-separator pointers */
  1070. fsh                   = strchr(fontspec,FONTSEP);    /* nominal font height        */
  1071. fst                   = strchr(fsh+1,FONTSEP);        /* type of font                */
  1072. vogltextattr->ta_Style= (UBYTE) 0;                    /* default style == plain    */
  1073. vogltextattr->ta_Flags= (UBYTE) 0;                    /* default style == plain    */
  1074.  
  1075. if(fsh) {
  1076.     sscanf(fsh+1,"%hu",&vogltextattr->ta_YSize);
  1077.     *fsh= '\0';
  1078.  
  1079.     if(fst) {
  1080.         for(++fst; *fst; ++fst) switch(*fst) {
  1081.  
  1082.         case 'B':    /* bold */
  1083.         case 'b':
  1084.             vogltextattr->ta_Style|= FSF_BOLD;
  1085.             break;
  1086.  
  1087.         case 'E':    /* extended (extra wide) */
  1088.         case 'e':
  1089.             vogltextattr->ta_Style|= FSF_EXTENDED;
  1090.             break;
  1091.  
  1092.         case 'I':    /* italic */
  1093.         case 'i':
  1094.             vogltextattr->ta_Style|= FSF_ITALIC;
  1095.             break;
  1096.  
  1097.         case 'P':    /* plain */
  1098.         case 'p':
  1099.             break;
  1100.  
  1101.         case 'U':    /* underlined */
  1102.         case 'u':
  1103.             vogltextattr->ta_Style|= FSF_UNDERLINED;
  1104.             break;
  1105.  
  1106.         default:    /* ignored */
  1107.             break;
  1108.             }
  1109.         }
  1110.     }
  1111. else vogltextattr->ta_YSize= 11L;            /* default height == 11 pts    */
  1112.  
  1113. /* free up old ta_Name */
  1114. if(vogltextattr->ta_Name) {
  1115.     slen= strlen((char *) vogltextattr->ta_Name);
  1116.     if(slen & 1) ++slen;
  1117.     FreeMem(vogltextattr->ta_Name,slen*sizeof(char));
  1118.     vogltextattr->ta_Name= NULL;
  1119.     }
  1120. slen= strlen(fontspec) + 6;
  1121. if(slen & 1) ++slen;
  1122. vogltextattr->ta_Name= (STRPTR) AllocMem((LONG) slen*sizeof(char),MEMTYPE);
  1123. sprintf((char *) vogltextattr->ta_Name,"%s.font",fontspec);
  1124.  
  1125. if(fsh) *fsh= FONTSEP;                            /* restore *fsh            */
  1126.  
  1127.  
  1128. /* attempt to open requested font */
  1129. vogltextfont= OpenDiskFont(vogltextattr);        /* open the font        */
  1130. if(vogltextfont) {
  1131.     SetFont(voglrastport,vogltextfont);            /* set the font            */
  1132.  
  1133.     /* set up FontList */
  1134.     head_link(FontList,fontlisthd,"FontList");
  1135.     stralloc(fontlisthd->fontspec,fontspec,"fontspec");
  1136.     fontlisthd->textfont= vogltextfont;
  1137.     oldfontlist         = fontlisthd;
  1138.     vdevice.hheight     = fontlisthd->textfont->tf_YSize;
  1139.     vdevice.hwidth      = fontlisthd->textfont->tf_XSize;
  1140.     }
  1141. else {    /* failure to open requested font */
  1142.     vdevice.hheight= 0;
  1143.     vdevice.hwidth = 0;
  1144.     return 0;
  1145.     }
  1146.  
  1147. return 1;
  1148. }
  1149.  
  1150. /* -------------------------------------------------------------------------- */
  1151.  
  1152. /* AMIGA_char: outputs one char */
  1153. static int AMIGA_char(char c)
  1154. {
  1155.     char s[2];
  1156.  
  1157.     s[0]= c;
  1158.     s[1]= '\0';
  1159.     AMIGA_string(s);
  1160.     return(0);
  1161. }
  1162.  
  1163. /* -------------------------------------------------------------------------- */
  1164.  
  1165. /* AMIGA_string: Display a string at the current drawing position */
  1166. static int AMIGA_string(char *s)
  1167. {
  1168. /* set up the IntuiText */
  1169. voglitext->FrontPen = (UBYTE) currcolor;    /* set text's foreground color        */
  1170. voglitext->BackPen  = (UBYTE) 0;            /* background color ignored            */
  1171. voglitext->DrawMode = JAM1;                    /* just use fgd color                */
  1172.  
  1173. voglitext->LeftEdge = vdevice.cpVx;            /* set x position                    */
  1174. /* set y position            */
  1175. voglitext->TopEdge  = (short)(vdevice.sizeSy - vdevice.cpVy - vdevice.hheight);
  1176.  
  1177. voglitext->ITextFont= NULL;                    /* use default font                    */
  1178. strcpy((char *) voglstring,s);                /* copy user's string to voglstring    */
  1179. voglitext->IText    = voglstring;            /* print out voglstring                */
  1180. voglitext->NextText = NULL;                    /* no next text                        */
  1181.  
  1182. PrintIText(voglrastport,voglitext,0L,0L);    /* use printIText to render            */
  1183.  
  1184.     return(0);
  1185.  
  1186. }
  1187.  
  1188. /* -------------------------------------------------------------------------- */
  1189.  
  1190. /* AMIGA_fill: fill a polygon */
  1191. static int AMIGA_fill(  int  n,  int *x,  int *y)
  1192. {
  1193. int ifill;
  1194. // int result;
  1195.  
  1196. if(AreaMove(voglrastport,(long) x[0],(long) vdevice.sizeSy - y[0]) < 0) {
  1197.     printf("***warning*** unable to fill polygon with %d vertices\n",n);
  1198.     return(0);
  1199.     }
  1200.  
  1201. for(ifill= 1; ifill < n; ++ifill) {
  1202.     if(AreaDraw(voglrastport,(long) x[ifill],(long) vdevice.sizeSy - y[ifill]) < 0) {
  1203.         printf("***warning*** unable to fill polygon with %d vertices\n",n);
  1204.         return(0);
  1205.         }
  1206.     }
  1207.  
  1208. AreaEnd(voglrastport);
  1209.  
  1210. vdevice.cpVx = x[n - 1];
  1211. vdevice.cpVy = y[n - 1];
  1212.  
  1213.     return(0);
  1214. }
  1215.  
  1216. /* -------------------------------------------------------------------------- */
  1217.  
  1218. /* AMIGA_backbuffer: draw in back buffer, display front
  1219.  *  Returns 0=success
  1220.  *         -1=failure
  1221.  */
  1222. static int AMIGA_backbuffer(void)
  1223. {
  1224. if(scrbufmode == SNGLBUFMODE) {    /* begin double buffer mode */
  1225.     scrbufmode                 = DBLBUFMODE;
  1226.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1227.     voglscreen->RastPort.Flags = DBUFFER;
  1228.     }
  1229.  
  1230. if(voglback && voglscreen->RastPort.BitMap != voglback) {
  1231.     MakeScreen(voglscreen);    /* make screen's new copper list            */
  1232.     RethinkDisplay();        /* combine copper lists into single View    */
  1233.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1234.     voglwindow->RPort->BitMap  = voglback;
  1235.     }
  1236.  
  1237. return 0;
  1238. }
  1239.  
  1240. /* -------------------------------------------------------------------------- */
  1241.  
  1242. /* AMIGA_swapbuffer: swap the front and back buffers */
  1243. static int AMIGA_swapbuffer(void)
  1244. {
  1245. struct BitMap *voglswap;
  1246.  
  1247. if(!voglback || scrbufmode != DBLBUFMODE) {
  1248.     return 0;
  1249.     }
  1250.  
  1251. /* display back buffer */
  1252. MakeScreen(voglscreen);    /* make screen's new copper list            */
  1253. RethinkDisplay();        /* combine copper lists into single View    */
  1254.  
  1255. /* swap front and back BitMap buffers */
  1256. voglswap                   = voglfront;
  1257. voglfront                  = voglback;
  1258. voglback                   = voglswap;
  1259. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1260. voglwindow->RPort->BitMap  = voglback;
  1261.  
  1262. return 0;
  1263. }
  1264.  
  1265. /* -------------------------------------------------------------------------- */
  1266.  
  1267. /* AMIGA_frontbuffer: draw in the front buffer */
  1268. static int AMIGA_frontbuffer(void)
  1269. {
  1270.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglfront;
  1271.     voglwindow->RPort->BitMap  = voglfront;
  1272.     return(0);
  1273. }
  1274.  
  1275. /* --------------------------------------------------------------------------
  1276.  * _AMIGA_devcpy
  1277.  *
  1278.  *    copy the amiga device into vdevice.dev.
  1279.  */
  1280. void _AMIGA_devcpy(void)
  1281. {
  1282. vdevice.dev= amigadev;
  1283. }
  1284.  
  1285. /* ==========================================================================
  1286.  * Source Code:
  1287.  *  The test code here exercises the amiga driver by itself and is not
  1288.  *  expected to be the "usual" way of using it.  The usual way is via
  1289.  *  standard vogl methods.
  1290.  */
  1291.  
  1292. /* --------------------------------------------------------------------- */
  1293.  
  1294. /* DT_title: this function sets up the window's title */
  1295. void DT_title(char *buf)
  1296. {
  1297. static char titlebuf[RAWKEYBUF];
  1298.  
  1299. strcpy(titlebuf,buf);
  1300. vdevice.wintitle= titlebuf;
  1301. }
  1302.  
  1303. /* --------------------------------------------------------------------- */
  1304.  
  1305. #ifdef SASC
  1306. void __regargs __checkabort (void)
  1307. {
  1308. /* empty */
  1309. }
  1310. #endif
  1311.  
  1312. /* --------------------------------------------------------------------- */
  1313.  
  1314.